package linc.fun.openai.service.impl;

import cn.hutool.core.util.RandomUtil;
import com.mybatisflex.core.query.QueryWrapper;
import com.mybatisflex.spring.service.impl.ServiceImpl;
import jakarta.annotation.Resource;
import linc.fun.openai.config.code.EmailConfig;
import linc.fun.openai.domain.entity.sys.SysEmailVerifyCodeDO;
import linc.fun.openai.enums.SysEmailBizTypeEnum;
import linc.fun.openai.mapper.SysEmailVerifyCodeMapper;
import linc.fun.openai.service.SysEmailVerifyCodeService;
import linc.fun.openai.util.IdGenerator;
import linc.fun.openai.util.ThrowExceptionUtil;
import linc.fun.openai.util.WebUtil;
import org.springframework.stereotype.Service;

import java.time.Duration;
import java.time.LocalDateTime;

import static linc.fun.openai.domain.entity.chat.table.Tables.SysEmailVerifyCode;

/**
 * 邮箱验证码核销记录业务实现类
 *
 * @author CoDeleven
 */
@Service
public class SysEmailVerifyCodeServiceImpl extends ServiceImpl<SysEmailVerifyCodeMapper, SysEmailVerifyCodeDO> implements SysEmailVerifyCodeService {

    @Resource
    private EmailConfig emailConfig;
    @Resource
    private IdGenerator idGenerator;

    @Override
    public SysEmailVerifyCodeDO createVerifyCode(SysEmailBizTypeEnum emailBizTypeEnum, String identity) {
        SysEmailVerifyCodeDO verifyCode = new SysEmailVerifyCodeDO();
        Duration duration = Duration.ofMinutes(emailConfig.getVerifyCodeExpireMinutes());
        LocalDateTime expirationDateTime = LocalDateTime.now().plus(duration);
        verifyCode.setId(idGenerator.getId());
        verifyCode.setVerifyCode(RandomUtil.randomString(32));
        verifyCode.setIsUsed(false);
        verifyCode.setVerifyIp(WebUtil.getIp());
        verifyCode.setBizType(emailBizTypeEnum);
        verifyCode.setToEmailAddress(identity);
        verifyCode.setExpireAt(expirationDateTime);
        this.save(verifyCode);
        return verifyCode;
    }

    @Override
    public SysEmailVerifyCodeDO findAvailableByVerifyCode(String verifyCode) {
        return this.getOne(QueryWrapper.create()
                .where(SysEmailVerifyCode.VerifyCode.eq(verifyCode))
                .and(SysEmailVerifyCode.IsUsed.eq(false))
                .and(SysEmailVerifyCode.ExpireAt.gt(LocalDateTime.now())));
    }

    @Override
    public void verifySuccess(SysEmailVerifyCodeDO availableVerifyCode) {
        availableVerifyCode.setVerifyIp(WebUtil.getIp());
        availableVerifyCode.setIsUsed(true);
        QueryWrapper queryWrapper = QueryWrapper.create()
                // 乐观锁
                .where(SysEmailVerifyCode.IsUsed.eq(false))
                .and(SysEmailVerifyCode.Id.eq(availableVerifyCode.getId()));
        ThrowExceptionUtil.isFalse(this.update(availableVerifyCode, queryWrapper))
                .throwMessage("邮箱验证码核销失败");
    }
}




